package gui;

import gui.Main.ChangeListener;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class TextFrame extends JFrame{
	JTextPane jtp=new JTextPane();
	JScrollPane jsp;
	TextFrame(){
		this.setSize(600,400);
		this.setLocationRelativeTo(null);
		
		jtp.setFont(new Font("Consolas", Font.PLAIN, 14));
		jtp.setEditable(false);
		jsp=new JScrollPane(jtp);
		this.add(jsp,BorderLayout.CENTER);
		this.setVisible(true);
	}
	public void setText(String str){
		jtp.setText(str);
	}
}

class CODTextFrame extends TextFrame{
	private JButton jbSave;
	private LineNumberHeaderView header;
	CODTextFrame(){
		JToolBar jtb = new JToolBar("Microscript-Assembly Language Viewer");
		jtb.add(jbSave = new JButton("Save Assembly Language"));
		jbSave.setToolTipText("Save Assembly Language");
		jbSave.setFocusPainted(false);
		jbSave.setBorderPainted(false);
		this.add(jtb,BorderLayout.NORTH);
		
		ActionListener save=new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setDialogTitle("Save Assembly Language");
				if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
					File choosen = fileChooser.getSelectedFile();
					String name = choosen.getPath();
					int index = name.lastIndexOf('.');
					if (index < 0 || !name.substring(index + 1).toLowerCase().equals("asm")) {
						name += ".asm";
						choosen = new File(name);
					}
					if (choosen.exists()) {
						int n = JOptionPane.showConfirmDialog(null, "File exists. Save as "+choosen.getName()+" anyway?",
								"Save File", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
						if (n == JOptionPane.YES_OPTION){
							saveFile(choosen, jtp.getText());
							Main.setStatus("Saving "+choosen.getName()+" is successful!");
						}else
							Main.setStatus("Error in saving "+choosen.getName()+": user cancelled.");
					} else {
						saveFile(choosen, jtp.getText());
						Main.setStatus("Saving "+choosen.getName()+" is successful!");
					}
				}
			}
		};
		jbSave.addActionListener(save);
		
		header=new LineNumberHeaderView(1);
		header.setFont(jtp.getFont());
		jsp.setRowHeaderView(header);
		jtp.getDocument().addDocumentListener(new ChangeListener(jtp));
	}
	
	public static boolean saveFile(File f, String s) {
		FileWriter fw;
		try {
			fw = new FileWriter(f);
		} catch (IOException ex) {
			return false;
		}
		try {
			fw.write(s);
			fw.flush();
			fw.close();
		} catch (IOException e) {
			return false;
		}

		return true;
	}
	
	class ChangeListener implements DocumentListener {
	    public ChangeListener(JTextPane editor) {
	    }

	    public void changedUpdate(DocumentEvent e) {
	    }

	    public void insertUpdate(DocumentEvent e) {
	    	header.setLineNum(jtp.getDocument().getDefaultRootElement().getElementCount());
	    	header.repaint();
	    }

	    public void removeUpdate(DocumentEvent e) {
	    	header.setLineNum(jtp.getDocument().getDefaultRootElement().getElementCount());
	    	header.repaint();
	    }
	}
}

class SEMTextFrame extends TextFrame{
	private Style SuccessfulStyle, ErrorStyle;
	private int totalitem,errors;
	SEMTextFrame(){
		SuccessfulStyle = ((StyledDocument) jtp.getDocument()).addStyle("SuccessfulStyle", null);
		ErrorStyle = ((StyledDocument) jtp.getDocument()).addStyle("ErrorStyle", null);
		StyleConstants.setForeground(SuccessfulStyle, Color.GREEN);
		StyleConstants.setForeground(ErrorStyle, Color.RED);
		StyleConstants.setBold(SuccessfulStyle, true);
		StyleConstants.setBold(ErrorStyle, true);	
		this.setSize(900,300);
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		
		totalitem = 0;
		errors = 0;
	}
	void color(){
		int beginIndex=-1;
		int endIndex=jtp.getText().indexOf("\n",1);
		while(endIndex!=-1){
			totalitem ++;
			if(jtp.getText().charAt(beginIndex+1)=='E'){
				errors ++;
				((StyledDocument) jtp.getDocument()).setCharacterAttributes(beginIndex, endIndex-beginIndex,ErrorStyle,true);
			}else{
				((StyledDocument) jtp.getDocument()).setCharacterAttributes(beginIndex, endIndex-beginIndex,SuccessfulStyle,true);
			}
			beginIndex=endIndex;
			endIndex=jtp.getText().indexOf("\n",beginIndex+1);
		}
	}
	void colorRed(){
		((StyledDocument) jtp.getDocument()).setCharacterAttributes(0, jtp.getText().length(),ErrorStyle,true);
	}
	public void setText(String str){
		jtp.setText(str);
		color();
		this.setTitle(errors + " errors, (Filter matched " + totalitem + " items)");
		repaint();
	}
}
